# 很多的包 请求包 xml解析包 os 标准库 json pandas django
import requests
import csv
from lxml import etree  # 用于处理xml和html文档 主要用于数据的抓取 数据的清洗
import os  # 主要用操作系统相关的函数 比如 文件 目录 路径
import time
import pandas as pd
import re  # re模板 提供的正则表达式
import django  # python 框架

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'myDataVCar.settings')
django.setup()
from myApp.models import CarInformation


# 创建python爬虫类
class spider(object):
    def __init__(self):
        self.spiderUrl = ("https://www.dongchedi.com/motor/pc/car/rank_data?aid=1839&app_name=auto_web_pc&city_name"
                          "=周口&count=10&month=&new_energy_type=&rank_data_type=11&brand_id=&price"
                          "=&manufacturer=&outter_detail_type=&nation=0")
        self.headers = {
            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:126.0) Gecko/20100101 Firefox/126.0"}

    def init(self):
        if not os.path.exists("./temp.csv"):
            with open('./temp.csv', 'a', newline='', encoding='utf-8') as wf:
                # 写文件名字
                writer = csv.writer(wf)
                # 品牌的名字，车辆名称，图片 销售量，价格 ，厂商，排名，能源类型，上市的时间，保修期限
                writer.writerow(['brand', 'carName', 'carImg', 'saleVolume', 'price',
                                 'manufacturer', 'rank', 'carModel', 'energyType', 'marketTime', 'insure'])

    def get_page(self):
        with open('./spiderPage.txt', 'r') as r_f:
            # strip() 用于去除字符串和换行符 空格
            # [-1] 读到最后一个数据 为结束
            return r_f.readlines()[-1].strip()

    def set_page(self, newPage):
        with open('./spiderPage.txt', 'a') as a_f:
            a_f.write('\n' + str(newPage))

    def save_to_csv(self, resData):
        with open('./temp.csv', 'a', newline='', encoding='utf-8') as f:
            writer = csv.writer(f)
            writer.writerow(resData)

    def save_to_sql(self):
        data = self.clear_csv()
        for car in data:
            CarInformation.objects.create(
                brand=car[0],
                carName=car[1],
                carImg=car[2],
                saleVolume=car[3],
                price=car[4],
                manufacturer=car[5],
                rank=car[6],
                carModel=car[7],
                energyType=car[8],
                marketTime=car[9],
                insure=car[10],
            )

    def main(self):
        # 定义count 初始值 用于设置下一页的数值
        count = self.get_page()  # 获取数值
        params = {'offset': int(count)}
        print("我数据从第{}行开始爬取".format(int(count) + 1))
        # 获取url
        pageJson = requests.get(self.spiderUrl, headers=self.headers, params=params).json()
        # 根据json数据测试
        pageJson = pageJson['data']['list']
        try:
            # 循环获取里面的数据
            for index, car in enumerate(pageJson):
                # 创健数据 把读取的数据依次存入到数组里面去
                carData = []
                print("正在爬取第%d" % (index + 1) + '数据')
                # print(car['brand_name'])
                # 品牌的名称
                carData.append(car['brand_name'])
                # 车辆的名称
                carData.append(car['series_name'])
                # 车辆的图片
                carData.append(car['image'])
                # 销量
                carData.append(car['count'])
                # 价格 最大价格 最小价格
                price = []
                # print(car['min_price'])
                price.append(car['min_price'])
                price.append(car['max_price'])
                # 存入到carData数组
                carData.append(price)
                # 生产的厂商
                carData.append(car['sub_brand_name'])
                # 排名
                carData.append(car['rank'])
                carNumber = car['series_id']
                # 车辆参数列表
                infoHtml = requests.get('https://www.dongchedi.com/auto/params-carIds-x-%s' % carNumber,
                                        headers=self.headers)
                # 使用etree解析xpath 其实就是节点信息
                infoHtmlPath = etree.HTML(infoHtml.text)
                # /html/body/div[1]/div[1]/div/div/div[2]/div[2]/div[2]/div[4]/div[1]/label
                carModel = infoHtmlPath.xpath('//div[@data-row-anchor="jb"]/div[2]/div/text()')[0]
                carData.append(carModel)
                # 能源类型
                energyType = infoHtmlPath.xpath('//div[@data-row-anchor="fuel_form"]/div[2]/div/text()')[0]
                carData.append(energyType)
                # 上市的时间
                marketTime = infoHtmlPath.xpath('//div[@data-row-anchor="market_time"]/div[2]/div/text()')[0]
                carData.append(marketTime)
                # 保修期限
                insure = infoHtmlPath.xpath('//div[@data-row-anchor="period"]/div[2]/div/text()')[0]
                carData.append(insure)
                # 存入到csv
                self.save_to_csv(carData)

        except:
            pass
            # 打印测试
            # print(carData)
            # break
        # print(pageJson)
        self.set_page(int(count) + 10)
        self.main()

    def clear_csv(self):
        df = pd.read_csv('./temp.csv')
        df.dropna(inplace=True)  # 遇到空行删除
        df.drop_duplicates(inplace=True)  # 重复的数据
        print("总数据量%d" % df.shape[0])  # shape就是把总行数打印出来
        return df.values


if __name__ == '__main__':
    spiderObj = spider()
    # spiderObj.init()
    #spiderObj.main()
    spiderObj.save_to_sql()
